//
// Created by 33145 on 2023/4/18.
//

#ifndef SYLAR_MYSQL_CONNECTION_POOL_H
#define SYLAR_MYSQL_CONNECTION_POOL_H

#include <mysql/mysql.h>
#include <list>
#include <string>
#include <memory>

#include "sylar/thread.h"
#include "sylar/mysql/mysql_connection.h"
#include "sylar/log.h"

namespace sylar {
  namespace sql {
    class ConnectionPool {
    public:
      typedef std::shared_ptr<ConnectionPool> ptr;
      typedef sylar::Mutex MutexType;
    public:
      MySQL::ptr GetConnection();				 //获取数据库连接
      bool ReleaseConnection(MySQL::ptr conn); //释放连接
      int GetFreeConn();					 //获取连接
      void DestroyPool();					 //销毁所有连接

      //单例模式
      static ConnectionPool *GetInstance();

      void init(const std::string& user, const std::string& passWd ,int max_conn_cnt = 5, const std::string& databaseName = "Login",
                const std::string& url = "127.0.0.1", const std::string& port = "3306");

    private:
      ConnectionPool();
      ~ConnectionPool();

      int m_MaxConn;  //最大连接数
      int m_CurConn;  //当前已使用的连接数
      int m_FreeConn; //当前空闲的连接数
      std::list<MySQL::ptr> m_connList; //连接池
      MutexType m_mutex;
      Semaphore m_sem{5};

    public:
      std::string m_url;			    //主机地址
      std::string m_Port;		      //数据库端口号
      std::string m_User;		      //登陆数据库用户名
      std::string m_PassWord;	    //登陆数据库密码
      std::string m_DatabaseName; //使用数据库名
    };

    class connectionRAII{
    public:
      connectionRAII(MySQL::ptr* con, ConnectionPool* connPool);
      ~connectionRAII();

    private:
      MySQL::ptr conRAII;
      ConnectionPool* poolRAII;
    };

  }
}



#endif //SYLAR_MYSQL_CONNECTION_POOL_H
